home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / MPW181-5 / _SETUP.1 / maplay.cpp < prev    next >
C/C++ Source or Header  |  1997-04-19  |  10KB  |  373 lines

  1. /* maplay.cpp - MPEG audio decoder
  2.  
  3.     Changes to original maplay 1.2, made by Jeff Tsay:
  4.  
  5.    - Header, bitstream, and miscellaneous flags come from main program
  6.    - CRC and range check violations ignored.
  7.    - Playtime not printed
  8.     - Before every frame, maplay checks if the user has asked it to
  9.      stop or seek, which will be reflected in the maplay_args. Every
  10.      16 frames a message is sent to the parent telling it which frame
  11.      maplay is decoding. All this stuff is synchronized using a mutex.
  12.    - Eliminated reading of crc from maplay_args.
  13.    - Layer III decoder object used for layer III frames. */
  14.  
  15. /*
  16.  *  @(#) maplay.cc 1.20, last edit: 6/22/94 12:32:55
  17.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  18.  *  @(#) Berlin University of Technology
  19.  *
  20.  *  Many thanks for ideas and implementations to:
  21.  *  -> Jim Boucher (jboucher@flash.bu.edu)
  22.  *     for his idea and first implementation of 8 kHz u-law output
  23.  *  -> Louis P. Kruger (lpkruger@phoenix.princeton.edu)
  24.  *     for his implementation of the LinuxObuffer class
  25.  *
  26.  *  This program is free software; you can redistribute it and/or modify
  27.  *  it under the terms of the GNU General Public License as published by
  28.  *  the Free Software Foundation; either version 2 of the License, or
  29.  *  (at your option) any later version.
  30.  *
  31.  *  This program is distributed in the hope that it will be useful,
  32.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  33.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34.  *  GNU General Public License for more details.
  35.  *
  36.  *  You should have received a copy of the GNU General Public License
  37.  *  along with this program; if not, write to the Free Software
  38.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  39.  */
  40.  
  41. /*
  42.  *  Changes from version 1.1 to 1.2:
  43.  *    - minor changes to create a LinuxObuffer object
  44.  *    - minor changes for a u-law version, which creates 8 kHz u-law output
  45.  *      on an amd device or in stdout mode, if compiled with ULAW defined
  46.  *    - option -amd forces maplay to treat /dev/audio as an amd device
  47.  *      in the u-law version. This is helpful on some SPARC clones.
  48.  *    - iostreams manipulator calls like "cerr << setw (2) << ..." replaced by
  49.  *      "cerr.width (2); ..." due to problems with older GNU C++ releases.
  50.  */
  51.  
  52.  
  53. #ifdef  __WIN32__
  54. #define STRICT
  55. #include <windows.h>
  56. #include "mp2win.h"
  57. #else
  58.     // other operating system includes
  59. #endif // __WIN32__
  60.  
  61. #ifndef  GUI
  62. #include <iostream.h>  // for reporting errors
  63. #endif   // GUI
  64.  
  65. #include "all.h"
  66. #include "crc.h"
  67. #include "header.h"
  68. #include "subband.h"
  69. #include "sublay1.h"
  70. #include "sublay2.h"
  71. #include "synfilt.h"
  72. #include "ibitstr.h"
  73. #include "obuffer.h"
  74. #include "args.h"
  75. #include "layer3.h"
  76.  
  77. #ifdef SEEK_STOP
  78. #include "mutx_imp.h"
  79. #endif
  80.  
  81. SynthesisFilter *filter1 = NULL, *filter2 = NULL;
  82. Obuffer *buffer = NULL;
  83. LayerIII_Decoder *l3decoder = NULL;
  84.  
  85. #pragma argsused
  86. void maplay_Exit(uint32 returncode)
  87. {
  88.  
  89. #ifdef SEEK_STOP
  90.   if ((returncode == 1) && buffer) {
  91.         buffer->set_stop_flag();
  92.   }
  93. #endif // SEEK_STOP
  94.  
  95.   delete buffer;
  96.   buffer = NULL;
  97.  
  98.   delete filter1;
  99.   filter1 = NULL;
  100.   delete filter2;
  101.   filter2 = NULL;
  102.  
  103.   delete l3decoder;
  104.   l3decoder = NULL;
  105. }
  106.  
  107. uint32 maplay(MPEG_Args *maplay_args)
  108. {
  109.     uint32 layer;
  110.     enum e_mode mode;
  111.  
  112.    BOOL read_ready = FALSE, write_ready = FALSE;
  113.  
  114.    // These arguments should not change while decoding
  115.     Crc16 *crc         = NULL;
  116.    Ibitstream *stream = maplay_args->stream;
  117.    Header *header     = maplay_args->MPEGheader;
  118.     enum e_channels which_channels = maplay_args->which_c;
  119.  
  120. #ifdef SEEK_STOP
  121.    _Mutex mutex       = maplay_args->mutex;
  122. #endif
  123.  
  124. #ifdef WIN32GUI
  125.    HWND hWnd          = maplay_args->hWnd;
  126. #else
  127.     // copy your operating system dependent arguments here
  128. #endif // WIN32GUI
  129.  
  130.    // get info from header of first frame:
  131.    layer = header->layer();
  132.    if ((mode = header->mode()) == single_channel)
  133.        which_channels = left;
  134.  
  135.    // create filter(s):
  136.    {
  137.       real scalefactor = (maplay_args->use_own_scalefactor) ?
  138.                               maplay_args->scalefactor  :
  139.                          32768.0;
  140.  
  141.         filter1 = new SynthesisFilter(0, scalefactor);
  142.  
  143.        if ((mode != single_channel) && (which_channels == both))
  144.            filter2 = new SynthesisFilter(1, scalefactor);
  145.    }
  146.  
  147.    // create buffer, and check to see if created ok:
  148.  
  149.    buffer = (maplay_args->stdout_mode) ?
  150.                create_stdout_obuffer(maplay_args) :
  151.                create_obuffer(maplay_args);
  152.  
  153.    if (buffer == NULL) {
  154.         maplay_Exit(0);
  155.       return(1);
  156.    }
  157.  
  158.   // Layer III : initialize decoder
  159.  
  160.       if (layer == 3)
  161.       l3decoder = new LayerIII_Decoder(stream, header,
  162.                                                     filter1, filter2,
  163.                                        buffer, which_channels);
  164.  
  165.    do
  166.    {
  167.  
  168. #ifdef SEEK_STOP
  169.  
  170.      mtx_lock(mutex);
  171.  
  172.      if (maplay_args->stop) {
  173.       maplay_Exit(1);
  174.       mtx_unlock(mutex);
  175.       return(0);
  176.     }
  177.  
  178.      if (maplay_args->position_change) {
  179.  
  180.         buffer->clear_buffer();
  181.  
  182.       if (!header->stream_seek(stream, maplay_args->desired_position)) {
  183.           maplay_Exit(0);
  184.           mtx_unlock(mutex);
  185.          return(1);
  186.       }
  187.  
  188.         maplay_args->position_change = FALSE;
  189.  
  190.       if (l3decoder)
  191.             l3decoder->seek_notify();
  192.  
  193.         // notify the parent of the current position
  194.  
  195. #ifdef WIN32GUI
  196.         PostMessage(hWnd, SEEK_ACK, NULL, NULL);
  197.         PostMessage(hWnd, SCROLL_POS, stream->current_frame(), 0);
  198. #else
  199.  
  200. #endif // WIN32GUI
  201.  
  202.      }
  203.  
  204.      // Send notification to the scroll bar every 16 frames
  205.     {
  206.       int32 cf = stream->current_frame();
  207.       if (!(cf & 0xf) && !(maplay_args->stop)) {
  208.  
  209.         // Notify the parent of the current position
  210.  
  211. #ifdef WIN32GUI
  212.                PostMessage(hWnd, SCROLL_POS, cf, 0);
  213. #else
  214.  
  215. #endif // WIN32GUI
  216.       }
  217.  
  218.     mtx_unlock(mutex);
  219.     }
  220.  
  221. #endif // SEEK_STOP
  222.  
  223.      // is there a change in important parameters?
  224.      // (bitrate switching is allowed)
  225.      if (header->layer() != layer)
  226.      {
  227.         // layer switching is allowed
  228.  
  229.       if (header->layer() == 3) {
  230.          l3decoder = new LayerIII_Decoder(stream, header,
  231.                                                        filter1, filter2,
  232.                                           buffer, which_channels);
  233.       } else if (layer == 3) {
  234.           delete l3decoder;
  235.          l3decoder = NULL;
  236.       }
  237.  
  238.         layer = header->layer();
  239.      }
  240.  
  241.      if (layer != 3) {
  242.  
  243.         Subband *subbands[32];
  244.         uint32 num_subbands = header->number_of_subbands();
  245.        mode = header->mode();
  246.  
  247.          // create subband objects:
  248.          if (layer == 1)
  249.          {
  250.             if (mode == single_channel)
  251.                 for (uint32 i = 0; i < num_subbands; ++i)
  252.                   subbands[i] = new SubbandLayer1(i);
  253.             else if (mode == joint_stereo) {
  254.              uint32 i;
  255.                 for (i = 0; i < header->intensity_stereo_bound(); ++i)
  256.                   subbands[i] = new SubbandLayer1Stereo(i);
  257.                 for (; i < num_subbands; ++i)
  258.                   subbands[i] = new SubbandLayer1IntensityStereo(i);
  259.             } else {
  260.                 for (uint32 i = 0; i < num_subbands; ++i)
  261.                   subbands[i] = new SubbandLayer1Stereo(i);
  262.           }
  263.  
  264.          } else { // Layer II
  265.             if (mode == single_channel)
  266.                 for (uint32 i = 0; i < num_subbands; ++i)
  267.                  subbands[i] = new SubbandLayer2(i);
  268.             else if (mode == joint_stereo)
  269.             {
  270.              uint32 i;
  271.                 for (i = 0; i < header->intensity_stereo_bound(); ++i)
  272.                      subbands[i] = new SubbandLayer2Stereo(i);
  273.                 for (; i < num_subbands; ++i)
  274.                     subbands[i] = new SubbandLayer2IntensityStereo(i);
  275.             } else {
  276.                 for (uint32 i = 0; i < num_subbands; ++i)
  277.                     subbands[i] = new SubbandLayer2Stereo(i);
  278.          }
  279.           }
  280.  
  281.           // start to read audio data:
  282.         for (uint32 i = 0; i < num_subbands; ++i)
  283.            subbands[i]->read_allocation(stream, header, crc);
  284.  
  285.          if (layer == 2)
  286.             for (uint32 i = 0; i < num_subbands; ++i)
  287.                 ((SubbandLayer2 *)subbands[i])->read_scalefactor_selection(stream,
  288.                                                                                          crc);
  289.  
  290.          if (!crc || header->checksum_ok())
  291.          {
  292.             // no checksums or checksum ok, continue reading from stream:
  293.             for (uint32 i = 0; i < num_subbands; ++i)
  294.                 subbands[i]->read_scalefactor(stream, header);
  295.  
  296.             do
  297.             {
  298.                 for (uint32 i = 0; i < num_subbands; ++i)
  299.                     read_ready = subbands[i]->read_sampledata(stream);
  300.  
  301.                 do
  302.                 {
  303.                     for (uint32 i = 0; i < num_subbands; ++i)
  304.                         write_ready = subbands[i]->put_next_sample(which_channels,
  305.                                                               filter1, filter2);
  306.  
  307.                     filter1->calculate_pcm_samples(buffer);
  308.                     if ((which_channels == both) && (mode != single_channel))
  309.                    filter2->calculate_pcm_samples(buffer);
  310.                 } while (!write_ready);
  311.             } while (!read_ready);
  312.  
  313.           buffer->write_buffer(1);
  314.  
  315.          } // checksum ok
  316.      // Jeff : Don't let user know if crc violated.
  317. //        else
  318.         // Sh*t! Wrong crc checksum in frame!
  319. //        cerr << "WARNING: frame contains wrong crc checksum! (throwing frame away)\n";
  320.  
  321.        for (uint32 i = 0; i < num_subbands; ++i) {
  322.             delete subbands[i];
  323.         }
  324.  
  325.     } else {  // Layer III
  326.        l3decoder->decode();
  327.     }
  328.  
  329.    }
  330.    while (header->read_header(stream, &crc));
  331.  
  332.    quit:
  333.  
  334. #ifdef SEEK_STOP
  335.  
  336.    mtx_lock(mutex);
  337.  
  338.    if (!maplay_args->stop) {
  339.  
  340.       // notify the parent of the last frame
  341.  
  342. #ifdef WIN32GUI
  343.       PostMessage(hWnd, SCROLL_POS, stream->current_frame(), 0);
  344. #else
  345.  
  346. #endif // WIN32GUI
  347.     }
  348.  
  349. #endif // SEEK_STOP
  350.  
  351.    maplay_Exit(0);
  352.  
  353. #ifdef SEEK_STOP
  354.    maplay_args->done = TRUE;
  355.  
  356.    if (!maplay_args->stop) {
  357.  
  358.      // tell the parent that we are done
  359.  
  360. #ifdef WIN32GUI
  361.         PostMessage(hWnd, WM_THREADEND, NULL, NULL);
  362. #else
  363.  
  364. #endif // WIN32GUI
  365.     }
  366.  
  367.    mtx_unlock(mutex);
  368.  
  369. #endif // SEEK_STOP
  370.  
  371.    return(0);
  372. }
  373.